package pl.auction_search.jobs;

import java.util.List;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.ISafeRunnable;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.SafeRunner;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;

import pl.auction_search.command.IShowResultCommand;
import pl.auction_search.search.ISearcher;
import pl.auction_search.search.Result;
import pl.auction_search.search.SearchHelper;

/**
 * Search job, doing the actual query
 **/
public final class SearchJob extends Job {
	protected IShowResultCommand doAfterResult;
	protected final String query;

	public SearchJob(final String query, IShowResultCommand doAfterResult) {
		super(query);
		this.query = query;
		this.doAfterResult = doAfterResult;
	}

	protected IStatus run(final IProgressMonitor monitor) {
		List<ISearcher> listRegisteredSearchers = SearchHelper.listRegisteredSearchers();

		if (monitor.isCanceled() || SearchHelper.isEmpty(listRegisteredSearchers)) {
			return Status.CANCEL_STATUS;

		} else {
			monitor.beginTask(getTaskName(), listRegisteredSearchers.size());

			searchUsing(listRegisteredSearchers); // ??? 

			monitor.done();
		}

		return Status.OK_STATUS;
	}

	/**
	 * Populate view with results from operation using passed command
	 **/
	protected void updateModel(List<Result> results) {
		doAfterResult.getResults().addAll(results);
		doAfterResult.run();
	}

	/**
	 * iterate over the extension list - and do the search.
	 **/
	protected void searchUsing(final List<ISearcher> listRegisteredSearchers) {
		for (final ISearcher iSearcher : listRegisteredSearchers) {
			final ISafeRunnable runnable = new ISafeRunnable() {
				@Override public void handleException(final Throwable exception) {
					SearchHelper.handleException(exception);
				}

				@Override public void run() throws Exception {
					List<Result> results = ((ISearcher) iSearcher).search(query);
					updateModel(results);
				}
			};
			SafeRunner.run(runnable);
		}
	}

	private String getTaskName() {
		return "Searching for '" + query + "'";
	}
}
